#include "widget.h"
#include "ui_widget.h"
#include <QClipboard>
#include <QCryptographicHash>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->masterPwd, &QLineEdit::textChanged, this, &Widget::updatePwd);
    connect(ui->domainName, &QLineEdit::textChanged, this, &Widget::updatePwd);
    connect(ui->pwdLen, &QSpinBox::valueChanged, this, &Widget::updatePwd);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_copyButton_clicked()
{
    QGuiApplication::clipboard()->setText(ui->pwdLabel->text());
}

void Widget::updatePwd(void)
{
    QString master = ui->masterPwd->text();
    QString site = ui->domainName->text();

    QString pwd = genPwd(master, site);

    ui->pwdLabel->setText(pwd);
}

QString Widget::genPwd(const QString& master, const QString& site)
{
    // Initialize HMAC-SHA1
    QCryptographicHash hash(QCryptographicHash::Sha1);
    QByteArray innerKeyPad(64, 0x36);
    QByteArray outerKeyPad(64, 0x5c);

    QByteArray key = master.toUtf8();
    QByteArray data = site.toUtf8();

    // XOR key with inner and outer pad
    for (int i = 0; i < key.length() && i < 64; ++i) {
        innerKeyPad[i] ^= key[i];
        outerKeyPad[i] ^= key[i];
    }

    // Calculate HMAC
    hash.reset();
    hash.addData(innerKeyPad);
    hash.addData(data);
    QByteArray innerHash = hash.result();

    hash.reset();
    hash.addData(outerKeyPad);
    hash.addData(innerHash);
    QByteArray hmac = hash.result();

    // Convert to Base64 and return
    return hmac.toBase64().left(ui->pwdLen->value()); // Return first N characters
}
